import { ref, onMounted, onUnmounted, computed } from 'vue'

// 断点定义
export const breakpoints = {
  xs: 0,
  sm: 640,
  md: 768,
  lg: 1024,
  xl: 1280,
  xxl: 1536
} as const

export type Breakpoint = keyof typeof breakpoints

// 响应式状态
const windowWidth = ref(0)

// 媒体查询监听器
const mediaQueries = new Map<Breakpoint, MediaQueryList>()

// 初始化媒体查询
const initMediaQueries = () => {
  if (typeof window === 'undefined') return
  
  Object.entries(breakpoints).forEach(([key, value]) => {
    if (value > 0) {
      const mq = window.matchMedia(`(min-width: ${value}px)`)
      mediaQueries.set(key as Breakpoint, mq)
    }
  })
}

// 更新窗口宽度
const updateWindowWidth = () => {
  if (typeof window !== 'undefined') {
    windowWidth.value = window.innerWidth
  }
}

// 响应式Hook
export function useResponsive() {
  onMounted(() => {
    updateWindowWidth()
    initMediaQueries()
    window.addEventListener('resize', updateWindowWidth)
  })
  
  onUnmounted(() => {
    if (typeof window !== 'undefined') {
      window.removeEventListener('resize', updateWindowWidth)
    }
  })
  
  // 当前断点
  const currentBreakpoint = computed<Breakpoint>(() => {
    const width = windowWidth.value
    
    if (width >= breakpoints.xxl) return 'xxl'
    if (width >= breakpoints.xl) return 'xl'
    if (width >= breakpoints.lg) return 'lg'
    if (width >= breakpoints.md) return 'md'
    if (width >= breakpoints.sm) return 'sm'
    return 'xs'
  })
  
  // 断点状态
  const isXs = computed(() => windowWidth.value >= breakpoints.xs && windowWidth.value < breakpoints.sm)
  const isSm = computed(() => windowWidth.value >= breakpoints.sm && windowWidth.value < breakpoints.md)
  const isMd = computed(() => windowWidth.value >= breakpoints.md && windowWidth.value < breakpoints.lg)
  const isLg = computed(() => windowWidth.value >= breakpoints.lg && windowWidth.value < breakpoints.xl)
  const isXl = computed(() => windowWidth.value >= breakpoints.xl && windowWidth.value < breakpoints.xxl)
  const isXxl = computed(() => windowWidth.value >= breakpoints.xxl)
  
  // 大于等于某个断点
  const isSmUp = computed(() => windowWidth.value >= breakpoints.sm)
  const isMdUp = computed(() => windowWidth.value >= breakpoints.md)
  const isLgUp = computed(() => windowWidth.value >= breakpoints.lg)
  const isXlUp = computed(() => windowWidth.value >= breakpoints.xl)
  const isXxlUp = computed(() => windowWidth.value >= breakpoints.xxl)
  
  // 小于等于某个断点
  const isXsDown = computed(() => windowWidth.value < breakpoints.sm)
  const isSmDown = computed(() => windowWidth.value < breakpoints.md)
  const isMdDown = computed(() => windowWidth.value < breakpoints.lg)
  const isLgDown = computed(() => windowWidth.value < breakpoints.xl)
  const isXlDown = computed(() => windowWidth.value < breakpoints.xxl)
  
  // 设备类型判断
  const isMobile = computed(() => windowWidth.value < breakpoints.md)
  const isTablet = computed(() => windowWidth.value >= breakpoints.md && windowWidth.value < breakpoints.lg)
  const isDesktop = computed(() => windowWidth.value >= breakpoints.lg)
  
  // 获取响应式值
  const getResponsiveValue = <T>(
    values: Partial<Record<Breakpoint, T>> | T,
    fallback?: T
  ): T | undefined => {
    if (typeof values !== 'object' || values === null) {
      return values as T
    }
    
    const breakpointOrder: Breakpoint[] = ['xxl', 'xl', 'lg', 'md', 'sm', 'xs']
    const current = currentBreakpoint.value
    
    // 首先检查当前断点
    if (current in values) {
      return (values as Record<Breakpoint, T>)[current]
    }
    
    // 向下查找
    const currentIndex = breakpointOrder.indexOf(current)
    for (let i = currentIndex + 1; i < breakpointOrder.length; i++) {
      const bp = breakpointOrder[i]
      if (bp in values) {
        return (values as Record<Breakpoint, T>)[bp]
      }
    }
    
    return fallback
  }
  
  // 匹配断点
  const matchBreakpoint = (breakpoint: Breakpoint): boolean => {
    return currentBreakpoint.value === breakpoint
  }
  
  // 在断点范围内
  const betweenBreakpoints = (min: Breakpoint, max: Breakpoint): boolean => {
    const width = windowWidth.value
    return width >= breakpoints[min] && width < breakpoints[max]
  }
  
  return {
    // 窗口宽度
    windowWidth: windowWidth.value,
    
    // 当前断点
    currentBreakpoint,
    
    // 精确断点
    isXs,
    isSm,
    isMd,
    isLg,
    isXl,
    isXxl,
    
    // 大于等于断点
    isSmUp,
    isMdUp,
    isLgUp,
    isXlUp,
    isXxlUp,
    
    // 小于等于断点
    isXsDown,
    isSmDown,
    isMdDown,
    isLgDown,
    isXlDown,
    
    // 设备类型
    isMobile,
    isTablet,
    isDesktop,
    
    // 工具函数
    getResponsiveValue,
    matchBreakpoint,
    betweenBreakpoints
  }
}

// 断点监听Hook
export function useBreakpointListener(breakpoint: Breakpoint, callback: (matches: boolean) => void) {
  onMounted(() => {
    if (typeof window === 'undefined') return
    
    const mq = window.matchMedia(`(min-width: ${breakpoints[breakpoint]}px)`)
    
    // 初始调用
    callback(mq.matches)
    
    // 监听变化
    const handler = (e: MediaQueryListEvent) => {
      callback(e.matches)
    }
    
    mq.addEventListener('change', handler)
    
    // 清理
    onUnmounted(() => {
      mq.removeEventListener('change', handler)
    })
  })
}

// 容器查询Hook (实验性)
export function useContainerQuery(containerRef: Ref<HTMLElement | null>, breakpoint: number) {
  const matches = ref(false)
  
  onMounted(() => {
    if (!containerRef.value || typeof window === 'undefined' || !('ResizeObserver' in window)) {
      return
    }
    
    const observer = new ResizeObserver((entries) => {
      for (const entry of entries) {
        const { inlineSize } = entry.contentBoxSize[0]
        matches.value = inlineSize >= breakpoint
      }
    })
    
    observer.observe(containerRef.value)
    
    onUnmounted(() => {
      observer.disconnect()
    })
  })
  
  return matches
}

// 媒体查询Hook
export function useMediaQuery(query: string) {
  const matches = ref(false)
  
  onMounted(() => {
    if (typeof window === 'undefined') return
    
    const mq = window.matchMedia(query)
    matches.value = mq.matches
    
    const handler = (e: MediaQueryListEvent) => {
      matches.value = e.matches
    }
    
    mq.addEventListener('change', handler)
    
    onUnmounted(() => {
      mq.removeEventListener('change', handler)
    })
  })
  
  return matches
}

// 预设媒体查询
export function usePrefersDark() {
  return useMediaQuery('(prefers-color-scheme: dark)')
}

export function usePrefersReducedMotion() {
  return useMediaQuery('(prefers-reduced-motion: reduce)')
}

export function usePrefersHighContrast() {
  return useMediaQuery('(prefers-contrast: high)')
}

export function useOrientation() {
  const isLandscape = useMediaQuery('(orientation: landscape)')
  const isPortrait = computed(() => !isLandscape.value)
  
  return {
    isLandscape,
    isPortrait
  }
}

// 视口尺寸Hook
export function useViewport() {
  const width = ref(0)
  const height = ref(0)
  
  const updateSize = () => {
    if (typeof window !== 'undefined') {
      width.value = window.innerWidth
      height.value = window.innerHeight
    }
  }
  
  onMounted(() => {
    updateSize()
    window.addEventListener('resize', updateSize)
  })
  
  onUnmounted(() => {
    if (typeof window !== 'undefined') {
      window.removeEventListener('resize', updateSize)
    }
  })
  
  return {
    width,
    height,
    aspectRatio: computed(() => width.value / height.value)
  }
}